package com.example.jufou;

import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.GestureDescription;
import android.content.ContentValues;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Path;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.provider.MediaStore;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityWindowInfo;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import okhttp3.Response;

public class HelpService extends AccessibilityService {
    public static final String  TAG = "愉聚辅助";
    public static final String 群列表 = "com.team.jufou:id/swipemenu";//向上两父级才能点击
    public static final String 多功能ICON = "com.team.jufou:id/emotion_photo";
    public static final String 选择图片按钮 = "com.team.jufou:id/btnCheck";
    public static final String 发送图片按钮 = "com.team.jufou:id/picture_tv_ok";
    public static final String 正在发送标识 ="com.team.jufou:id/send_progress";
    public static final String 文件框 ="com.team.jufou:id/edit_text";
    public static final String 发送消息按钮 = "com.team.jufou:id/emotion_send";
    public static final String 聊天界面 = "com.team.jufou:id/rl_nav_message";
    public static final String 麦克风图标 = "com.team.jufou:id/emotion_voice";
    public static volatile boolean linser = true;//是否监听动作

    public static Handler handle = new Handler();
    private File appDir = new File(Environment.getExternalStorageDirectory()+"/DCIM", "Camera");
    private static ScheduledExecutorService service;
    private final static ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

    public  void onDestroy(){
        if(service!=null){
            try {
                service.shutdownNow();
            }catch (Exception e){e.printStackTrace();}
        }
    }
    @Override
    public void onInterrupt() {
        //Log.d(TAG,"监听中断");
        execShell("settings put secure enabled_accessibility_services com.team.jufou/com.example.jufou.HelperService");
        execShell("settings put secure accessibility_enabled 1");
        HelpService.linser = true;
        Common.sendTag = false;
        newService(120,60);
        //Log.d(TAG,"重新拉起会和辅助");
    }

    @Override
    protected void onServiceConnected() {
        if(!appDir.exists()){
            appDir.mkdir();
        }
        Common.sendTag = false;
        HelpService.linser = true;
        清缓存();
        newService(120,60);
    }

    List<String> tempImgName = new ArrayList<>();
    Long lastPictureTime = System.currentTimeMillis();

    public static  volatile long thread1 = 0;
    public static  volatile long thread2 = 0;
    Long 最后请求网络时间 = null;

    public void newService(int initialDelay1,int initialDelay2){
        if(service!=null){
            try {
                service.shutdownNow();
            }catch (Exception e){e.printStackTrace();}
        }
        service = Executors.newScheduledThreadPool(1);
        service.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                try {
                    thread1 = System.currentTimeMillis();
                    //Log.d(TAG, "自我检查");
                    if (最后请求网络时间 != null && System.currentTimeMillis() - 最后请求网络时间 > 21 * 1000) {//20秒没有网络请求则启动返回按钮
                        HelpService.linser = false;
                        handle.post(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
                                    performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
                                        Thread.sleep(500L);
                                    performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
                                    performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
                                    HelpService.linser = true;
                                    Common.sendTag = false;
                                    startActivity(getPackageManager().getLaunchIntentForPackage("com.team.jufou"));
                                }catch (Exception e){}

                            }
                        });
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }, initialDelay1, 22, TimeUnit.SECONDS);//2分钟后每隔22秒检测一次网络请求
        //防止相册点不动
        service.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                try {
                    thread2 = System.currentTimeMillis();
                    if (!Common.sendTag && 判断是否有图片()) {
                        File[] files = appDir.listFiles();
                        if (files.length > 0) {
                            List<String> list = new ArrayList<>(files.length);
                            boolean flag = false;
                            for (int i = 0; i < files.length; i++) {
                                if (files[i].isFile() && files[i].getName().endsWith(".jpg")) {
                                    list.add(files[i].getName());
                                }
                            }
                            if (list.retainAll(tempImgName)) {//存在交集
                                handle.postDelayed(new Runnable() {
                                    @Override
                                    public void run() {
                                        //Log.d(TAG, "检查到相册图片执行点击操作");
                                        进入相册();
                                    }
                                }, 300);
                            }
                            tempImgName = list;
                        }
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        },initialDelay2,10,TimeUnit.SECONDS); //每隔10秒钟检查
    }

    public void onAccessibilityEvent(AccessibilityEvent event) {
        if(linser) {
            if(event.getEventType()==AccessibilityEvent.TYPE_VIEW_SCROLLED||"com.team.jufou.ui.activity.chat.ChatActivity".equals(event.getClassName().toString())){//可能是进群列表了
                //判断是否有麦克风图标进一步确认是否进群
                handle.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        if(获取麦克风图标(null)){//确认进群
                            if (!Common.sendTag && 判断是否有图片()) {//是否有图片可发送
                                handle.postDelayed(new Runnable() {
                                    @Override
                                    public void run() {
                                        if (!进入相册()) {//强制进入相
                                            handle.postDelayed(new Runnable() {
                                                @Override
                                                public void run() {
                                                    //Log.d(TAG, "强制点击相册");
                                                    int x1 = 45 + (171 - 45) / 2;
                                                    int y1 = 1794 + (1920 - 1794) / 2;
                                                    定点点击(x1, y1, 250, null);
                                                }
                                            },500L);

                                        }
                                    }
                                },300L);
                            } else if (Common.sendTag) {//判断图片是否发送完成
                                if (判断发送完成()) {
                                    //删除所有图片，重新请求网络
                                    handle.postDelayed(new Runnable() {
                                        @Override
                                        public void run() {
                                            if (Common.message != null) {
                                                写入消息();
                                            }
                                            删除所有图片();
                                            try {
                                                Thread.sleep(1000);
                                                Common.sendTag = false;
                                                请求网络(System.currentTimeMillis());
                                            } catch (InterruptedException e) {
                                                e.printStackTrace();
                                            }
                                        }
                                    }, 300);
                                }
                            } else {//只第一次才执行
                                handle.postDelayed(new Runnable() {
                                    @Override
                                    public void run() {
                                        if (Common.message != null) {
                                            写入消息();
                                        }
                                        请求网络(System.currentTimeMillis());
                                    }
                                }, 200);
                            }
                        }
                    }
                },200);
            }
            switch (event.getClassName().toString()){
                case "com.luck.picture.lib.PictureSelectorActivity"://相册界面
                    handle.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            if (!选择图片()) {
                                //Log.d(TAG, "无法获取到相册内信息");
                            } else {
                                handle.postDelayed(new Runnable() {
                                    @Override
                                    public void run() {
                                        发送图片();
                                    }
                                },650L);
                            }
                        }
                    },200);
                    break;
                case "com.team.jufou.ui.activity.MainActivity":
                    handle.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            if(进入聊天界面(new GestureResultCallback() {
                                public void onCompleted(GestureDescription gestureDescription) {
                                    handle.postDelayed(new Runnable() {
                                        @Override
                                        public void run() {
                                            进群();
                                        }
                                    },200);

                                }
                            })){//进入群

                            }
                        }
                    },100L);
                    break;
            }
            if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED) {
                if (发送消息()) {
                    handle.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            请求网络(System.currentTimeMillis());
                        }
                    }, 200);
                }
            }
        }
    }

    public boolean 获取麦克风图标(GestureResultCallback back){
        List<AccessibilityWindowInfo> infoList = getWindows();
        boolean flag = false;
        for(int i=0;i<infoList.size();i++) {
            AccessibilityNodeInfo info = infoList.get(i).getRoot();
            if(info==null){
                continue;
            }
            List<AccessibilityNodeInfo> list = info.findAccessibilityNodeInfosByViewId(麦克风图标);
            if (list != null && list.size() > 0) {
                for(int j=0;j<list.size();j++){
                    flag = true;
                    break;
                }

            }
            info.recycle();
        }
        return flag;
    }

    public boolean 进入聊天界面(GestureResultCallback back){
        List<AccessibilityWindowInfo> infoList = getWindows();
        boolean flag = false;
        for(int i=0;i<infoList.size();i++) {
            AccessibilityNodeInfo info = infoList.get(i).getRoot();
            if(info==null){
                continue;
            }
            List<AccessibilityNodeInfo> list = info.findAccessibilityNodeInfosByViewId(聊天界面);
            if (list != null && list.size() > 0) {
                for(int j=0;j<list.size();j++){
                    Log.d(TAG,"查找界面");
                    AccessibilityNodeInfo ani = list.get(j);
                    touch(ani, 250, back);
                    flag = true;
                    break;
                }

            }
            info.recycle();
        }
        return flag;
    }

    private synchronized void 请求网络(final Long time){
        if(time.longValue()!=Common.time.longValue()&&time.longValue()<Common.time.longValue()){//保证同时只有一个请求
            return;
        }
        HelpService.singleThreadExecutor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    最后请求网络时间 = System.currentTimeMillis();
                       Common.time = time;
                        HttpClient.getInstance(HelpService.this).post(Common.url+"/getList", Common.param, new HttpClient.MyCallback() {
                            public void success(Response res) throws IOException {
                                String str = res.body().string();
                                if (str != null && !str.trim().equals("")&&!str.equals("{}")) {
                                    try {
                                        Gson gson = new Gson();
                                        Map<String,Object> resultMap = gson.fromJson(str, new TypeToken<Map<String,Object>>() {}.getType());
                                        List<String> list = (List<String>) resultMap.get("pic");
                                        String message = (String) resultMap.get("message");
                                        if(!"暂无消息".equals(message)&&message!=null&&!message.trim().equals("")){
                                            Common.message = message;
                                        }else{
                                            Common.message = null;
                                        }
                                        if(list.size()>0){清缓存();}
                                        int i=0;
                                        for(;i<list.size()&&i<9;i++){//最多下9张多的丢掉
                                            try {
                                                String tempUrl = list.get(i);
                                                URL url = new URL(tempUrl);
                                                try (InputStream is = url.openConnection().getInputStream()) {
                                                    Bitmap bitmap = BitmapFactory.decodeStream(is);
                                                    saveImageToGallery(bitmap);
                                                }
                                            } catch (Exception e) {
                                                e.printStackTrace();
                                            }
                                        }
                                        if(i>0){//已保存图片
                                            handle.postDelayed(new Runnable() {
                                                @Override
                                                public void run() {
                                                    进入相册();
                                                }
                                            },300);
                                        }else if(Common.message!=null){
                                            handle.postDelayed(new Runnable() {
                                                @Override
                                                public void run() {
                                                    写入消息();
                                                }
                                            },300);
                                        }else{
                                            handle.postDelayed(new Runnable() {
                                                @Override
                                                public void run() {
                                                    请求网络(time);
                                                }
                                            },300);
                                        }
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                }else{
                                    handle.postDelayed(new Runnable() {
                                        @Override
                                        public void run() {
                                            请求网络(time);
                                        }
                                    },300);
                                }
                            }
                            public void failed(IOException e) {
                                handle.postDelayed(new Runnable() {
                                    @Override
                                    public void run() {
                                        请求网络(time);
                                    }
                                },300);
                            }
                        });
                    }catch(Exception e){
                        handle.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                请求网络(time);
                            }
                        },300);
                    }
            }
        });
    }

    public boolean 进群(){
        List<AccessibilityWindowInfo> infoList = getWindows();
        boolean flag = false;
        try{
            for(int i=0;i<infoList.size();i++) {
                AccessibilityNodeInfo info = infoList.get(i).getRoot();
                if(info==null){
                    continue;
                }
                List<AccessibilityNodeInfo> list = info.findAccessibilityNodeInfosByViewId(群列表);
                if (list != null && list.size() > 0) {
                    AccessibilityNodeInfo ani = list.get(0);
                    touch(ani, 250, new GestureResultCallback() {
                        public void onCompleted(GestureDescription gestureDescription) {
                            handle.postDelayed(new Runnable() {
                                @Override
                                public void run() {
                                    进群();
                                }
                            },500);

                        }
                    });
                    flag = true;
                }
                info.recycle();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return flag;
    }


    public boolean 进入相册(){
        List<AccessibilityWindowInfo> infoList = getWindows();
        boolean flag = false;
        try{
            for(int i=0;i<infoList.size();i++){
                AccessibilityNodeInfo info = infoList.get(i).getRoot();
                if(info==null){
                    continue;
                }
                List<AccessibilityNodeInfo> list = info.findAccessibilityNodeInfosByViewId(多功能ICON);
                if(list!=null&&list.size()>0){
                    AccessibilityNodeInfo ani = list.get(0);
                    touch(ani,250,new GestureResultCallback() {
                        public void onCompleted(GestureDescription gestureDescription) {
                            handle.postDelayed(new Runnable() {
                                @Override
                                public void run() {
                                    进入相册();
                                }
                            }, 300);

                        }
                    });
                    flag = true;
                }
                info.recycle();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return flag;
    }

    public boolean 选择图片(){
        List<AccessibilityWindowInfo> infoList = getWindows();
        boolean flag = false;
        for(int i=0;i<infoList.size();i++){
            AccessibilityNodeInfo info = infoList.get(i).getRoot();
            if(info==null){
                continue;
            }
            try{Thread.sleep(500L);}catch (Exception e){}
            List<AccessibilityNodeInfo> list = info.findAccessibilityNodeInfosByViewId(选择图片按钮);
            if(list!=null&&list.size()>0){
                for(int j=list.size()>9?9:list.size();j>0;j--){
                    AccessibilityNodeInfo ani = list.get(j-1);
                    touch(ani,250,null);
                    try{Thread.sleep(300L);}catch (Exception e){}
                }
                flag = true;
            }
            info.recycle();
        }
        if(!flag){
            File[] files = appDir.listFiles();
            if(files.length>0){
                for(int i=0;i<files.length;i++){
                    if(files[i].isFile()&&files[i].getName().endsWith(".jpg")){
                        Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                        Uri uri = Uri.fromFile(files[i]);
                        intent.setData(uri);
                        HelpService.this.sendBroadcast(intent);
                        try{Thread.sleep(200L);}catch (Exception e){}
                    }
                }
            }
            performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
        }
        return flag;
    }

    public boolean 发送图片(){
        List<AccessibilityWindowInfo> infoList = getWindows();
        boolean flag = false;
        for(int i=0;i<infoList.size();i++){
            AccessibilityNodeInfo info = infoList.get(i).getRoot();
            if(info==null){
                continue;
            }
            List<AccessibilityNodeInfo> list = info.findAccessibilityNodeInfosByViewId(发送图片按钮);
            if(list!=null&&list.size()>0){
                AccessibilityNodeInfo ani = list.get(0);
                if(ani.isEnabled()) {
                    touch(ani, 250, null);
                    lastPictureTime = System.currentTimeMillis();
                    flag = true;
                    Common.sendTag = flag;
                }

            }
            info.recycle();
        }
        if(!flag){
            performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
        }
        return flag;
    }

    public boolean 写入消息(){
        List<AccessibilityWindowInfo> infoList = getWindows();
        boolean flag = false;
        for(int i=0;i<infoList.size();i++){
            AccessibilityNodeInfo info = infoList.get(i).getRoot();
            if(info==null){
                continue;
            }
            List<AccessibilityNodeInfo> list = info.findAccessibilityNodeInfosByViewId(文件框);
            if(list!=null&&list.size()>0){
                AccessibilityNodeInfo ani = list.get(0);
                Bundle arguments = new Bundle();
                arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, Common.message);
                ani.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);
                flag = true;
                Common.message = null;
            }
            info.recycle();
        }
        if(!flag){
            performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
        }
        return flag;
    }

    public boolean 发送消息(){
        List<AccessibilityWindowInfo> infoList = getWindows();
        boolean flag = false;
        try{
            for(int i=0;i<infoList.size();i++){
                AccessibilityNodeInfo info = infoList.get(i).getRoot();
                if(info==null){
                    continue;
                }
                List<AccessibilityNodeInfo> list = info.findAccessibilityNodeInfosByViewId(发送消息按钮);
                if(list!=null&&list.size()>0){
                    AccessibilityNodeInfo ani = list.get(0);
                    touch(ani,250,null);
                    flag = true;
                }
                info.recycle();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return flag;
    }

    public boolean 判断发送完成(){
        List<AccessibilityWindowInfo> infoList = getWindows();
        boolean flag = false;
        for(int i=0;i<infoList.size();i++){
            AccessibilityNodeInfo info = infoList.get(i).getRoot();
            if(info==null){
                continue;
            }
            List<AccessibilityNodeInfo> list = info.findAccessibilityNodeInfosByViewId(正在发送标识);
            if(list!=null&&list.size()>0){
                try{Thread.sleep(500L);}catch (Exception e){}
                flag = true;
            }
            info.recycle();
        }
        if(flag){
            return 判断发送完成();
        }
        return true;
    }



    /**
     * 保存到pictrues
     */
    public   void  saveImageToGallery(Bitmap bitmap){
        if (!appDir.exists()) {
            appDir.mkdir();
        }
        String fileName = (Common.picName-System.currentTimeMillis()) + ".jpg";
        File file = new File(appDir, fileName);
        try {
            try(FileOutputStream fos = new FileOutputStream(file)) {
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
                fos.flush();
            }
            bitmap.recycle();
            //通知更新到相册
            Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
            Uri uri = Uri.fromFile(file);
            intent.setData(uri);
            HelpService.this.sendBroadcast(intent);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private boolean deleteImage(String imgPath) {
        try {
            File file = new File(imgPath);
            if(!file.exists()){
                return true;
            }
            if(file.isFile()) {
                boolean flag = file.delete();
                Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                Uri uri = Uri.fromFile(file);
                intent.setData(uri);
                HelpService.this.sendBroadcast(intent);
                return  flag;
            }else{
                File [] f = file.listFiles();
                for(int i=0;i<f.length;i++){
                    deleteImage(f[i].getAbsolutePath());
                }
                return file.delete();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return false;
    }

    private void 删除所有图片(){
        File[] file = appDir.listFiles();
        for(int i=0;i<file.length;i++){
            while(true) {
                boolean flag = deleteImage(file[i].getAbsolutePath());
                if(flag){
                    break;
                }
                try{
                    Thread.sleep(100L);
                }catch(Exception e){}
            }
        }
    }

    public boolean 判断是否有图片(){
        File[] files = appDir.listFiles();
        if(files.length>0){
            for(int i=0;i<files.length;i++){
                if(files[i].isFile()&&files[i].getName().endsWith(".jpg")){
                    return true;
                }
            }
            return false;
        }
        return false;
    }


    public void touch(AccessibilityNodeInfo info,int time,GestureResultCallback back){
        Rect rect = new Rect();
        info.getBoundsInScreen(rect);
        int x1 = rect.centerX();
        int y1 = rect.centerY();
        定点点击(x1,y1,time,back);
    }

    public void 定点点击(int x1,int y1,int time,GestureResultCallback back){
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            GestureDescription.Builder gestureBuilder = new GestureDescription.Builder();
            Path path = new Path();
            path.moveTo(x1,y1);
            gestureBuilder.addStroke(new GestureDescription.StrokeDescription(path, 0, time));
            dispatchGesture(gestureBuilder.build(),back!=null?back:null,null);
        }

    }

    public void 清缓存(){
        //清除会和图片缓存
        Thread thread = new Thread(new Runnable() {//重启线程处理避免卡死
            @Override
            public void run() {
                File dir = new File(Environment.getExternalStorageDirectory(), "Android/data/com.team.jufou");
                if(dir.exists()) {
                    File[] f = dir.listFiles();
                    for (int i = 0; i <f.length;i++){
                        清除愉聚图片缓存(f[i].getAbsolutePath());
                    }
                }

            }
        });
        thread.start();
    }
    public void 清除愉聚图片缓存(String parth){
        File dir = new File(parth);
        if(dir.isDirectory()){
            File[] file = dir.listFiles();
            for(int i=0;i<file.length;i++){
                清除愉聚图片缓存(file[i].getAbsolutePath());
            }
        }else{
            dir.delete();
        }
    }

    private  static void execShell(String cmd){
        try {
            Process p=Runtime.getRuntime().exec(cmd);
            BufferedReader br=new BufferedReader(new InputStreamReader(p.getInputStream()));
            String readLine=br.readLine();
            while(readLine!=null){
                readLine=br.readLine();
            }
            if(br!=null){
                br.close();
            }
            p.destroy();
            p=null;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

